/*
* 封装select2组件
* lzw
* 2021年8月9日
* */

class XnSelect extends React.Component {
    constructor(props) {
        super(props)
        this.state = { selected: props.selected || [] }
        this._cached = {}
    }

    render() {
        let inResult
        if (!this.state.items) inResult = <li className="select2-results__option un-hover text-muted">{$L('Searching')}</li>
        else if (this.state.items.length === 0) inResult = <li className="select2-results__option un-hover">{$L('NoResults')}</li>
        else {
            inResult = this.state.items.map((item) => {
                return (
                    <li key={`o-${item.teamId}`} className="select2-results__option" data-id={item.teamId} onClick={(e) => this.clickItem(e)}>
                        <i className={`zmdi ${!this.props.hideSelection && this.containsItem(item.teamId) ? ' zmdi-check' : ''}`}></i>

                        <span className="text">{item.teamName}</span>
                    </li>
                )
            })
        }

        const _DropdownMenu = (
            <div className="dropdown-menu">
                <div className="selector-search">
                    <div>
                        <input
                            type="search"
                            className="form-control search"
                            placeholder={$L('InputForSearch')}
                            value={this.state.query || ''}
                            ref={(c) => (this._input = c)}
                            onChange={(e) => this.searchItems(e)}
                            onKeyDown={(e) => this._keyEvent(e)}
                        />
                    </div>
                </div>
                <div className="tab-container m-0">
                    <div className="tab-content">
                        <div className="tab-pane active">
                            <div className="rb-scroller" ref={(c) => (this._scroller = c)}>
                                <ul className="select2-results__options">{inResult}</ul>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        )

        // Mix select2 and dropdown
        // data-reference="parent" data-offset="1,26"
        return (
            <span className="select2 select2-container select2-container--default user-selector" ref={elem => this.sl = elem}>
        <span className="selection">
          {this.props.compToggle ? (
              <span ref={(c) => (this._dropdownParent = c)}>
              {this.props.compToggle}
                  {_DropdownMenu}
            </span>
          ) : (
              <div className="select2-selection select2-selection--multiple">
                  <div className="select2-selection__rendered" ref={(c) => (this._dropdownParent = c)}>
                      {this.state.selected.length > 0 && (
                          <span className="select2-selection__clear" onClick={() => this.clearSelection()}>
                    &times;
                  </span>
                      )}
                      {this.state.selected.map((item) => {
                          return (
                              <span key={`s-${item.teamId}`} className="select2-selection__choice">
                      <span className="select2-selection__choice__remove" data-id={item.teamId} onClick={(e) => this.removeItem(e)}>
                        &times;
                      </span>{' '}
                                  {item.teamName}
                    </span>
                          )
                      })}
                      <span className="select2-selection__choice abtn" data-toggle="dropdown">
                  <a>
                    <i className="zmdi zmdi-plus" /> {this.props.multiple === false ? $L('Select') : $L('Add')}
                  </a>
                </span>
                      {_DropdownMenu}
                  </div>
              </div>
          )}
        </span>
      </span>
        )
    }
    getDataList(query=''){
        $.ajax({
            url:this.props.url,
            type:'POST',
            data:JSON.stringify({[this.props.queryKey]:query}),
            contentType:"application/json;charset=UTF-8",
            dataType: "JSON",
            success: (res)=> {
                if (res.error_code === 0 && res.data.pageList.records.length > 0) {
                    this.setState({ items: res.data.pageList.records })
                }
            }
        })
    }
    componentDidMount() {
        $(this._scroller).perfectScrollbar()

        const that = this
        $(this._dropdownParent).on({
            'show.bs.dropdown': function () {
                // 初始化
                if (!that.state.items) that.getDataList()
            },
            'shown.bs.dropdown': function () {
                that._input && that._input.focus()
                $(that._scroller).find('li.active').removeClass('active')
            },
            'hide.bs.dropdown': function (e) {
                if (!e.clickEvent || !e.clickEvent.target) return
                const $target = $(e.clickEvent.target)
                if ($target.hasClass('dropdown-menu') || $target.parents('.dropdown-menu').length === 1) {
                    if (that.props.multiple === false) {
                        if (!($target.hasClass('select2-results__options') || $target.parents('.select2-results__options').length === 1)) return false
                    } else {
                        return false
                    }
                }
            }
        })
        if (this.props.defaultValue) {
            let dv = this.props.defaultValue
            if ($.type(this.props.defaultValue) === 'string') dv = dv.split(',')
            this.getDataList()
        }
    }

    componentWillUnmount() {
        $(this._scroller).perfectScrollbar('destroy')
    }

    UNSAFE_componentWillReceiveProps(props) {
        this.setState({ selected: props.selected || this.state.selected })
    }

    clearSelection() {
        this.setState({ selected: [] }, () => {
            typeof this.props.onClearSelection === 'function' && this.props.onClearSelection()
        })
    }

    _tryActive($active, $el) {
        if ($el && $el.length === 1) {
            $active.removeClass('active')
            $el.addClass('active')

            const st = $(this._scroller).scrollTop()
            const et = $el.position().top
            if (et >= 0) {
                const top = et + st - (222 - 36) // maxHeight - elementHeight
                if (top > 0) $(this._scroller).scrollTop(top)
            } else {
                const top = st + et
                if (top >= 0) $(this._scroller).scrollTop(top)
            }
        }
    }

    _keyEvent(e) {
        if (e.keyCode === 40) {
            const $active = $(this._scroller).find('li.active')
            const $next = $active.length === 0 ? $(this._scroller).find('li:eq(0)') : $active.next()
            this._tryActive($active, $next)
        } else if (e.keyCode === 38) {
            const $active = $(this._scroller).find('li.active')
            const $prev = $active.length === 0 ? null : $active.prev()
            this._tryActive($active, $prev)
        } else if (e.keyCode === 13) {
            const $active = $(this._scroller).find('li.active')
            if ($active.length === 1) {
                $active.trigger('click')
                $stopEvent(e)
            }
        }
    }

    searchItems(e) {
        this.setState({ query: e.target.value }, () => {
            this.getDataList(this.state.query)
            //$setTimeout(() => this.switchTab(), 300, 'us-search-items')
        })
    }

    clickItem(e, isRemove) {
        const $target = $(e.currentTarget)
        const id = $target.data('id') || $target.parents('.select2-results__option').data('id')

        let exists = false
        let ns = []
        // 单选
        if (this.props.multiple !== false || isRemove) {
            ns = this.state.selected.filter((x) => {
                if (x.teamId === id) {
                    exists = true
                    return false
                }
                return true
            })
        }

        const selected = { teamId: id, teamName: $target.text() }

        if (!exists) ns.push(selected)
        if (ns.length >= 20) {
            RbHighbar.create($L('MaxSelectX').replace('%d', 20))
            return false
        }

        this.setState({ selected: ns }, () => {
            typeof this.props.onSelectItem === 'function' && this.props.onSelectItem(selected, isRemove)
        })
    }

    removeItem(e) {
        this.clickItem(e, true)
    }

    containsItem(id) {
        return !!this.state.selected.find((x) => x.teamId === id)
    }

    getSelected() {
        const ids = []
        this.state.selected.forEach((item) => ids.push(item.teamId))
        return ids
    }

    val() {
        return this.getSelected()
    }
    static _val() {
        return this.getSelected()
    }
}
/**
 * JSX 组件渲染
 *
 * @param {*} jsx
 * @param {*} target id or object of element (or function of callback)
 * @param {*} call callback
 */
const renderRbcomp = function (jsx, target, call) {
    if (typeof target === 'function') {
        call = target
        target = null
    }

    target = target || $random('react-container-')
    if ($.type(target) === 'string') {
        // element id
        const container = document.getElementById(target)
        if (!container) {
            if (!target.startsWith('react-container-')) throw 'No element found : ' + target
            else target = $(`<div id="${target}"></div>`).appendTo(document.body)[0]
        } else {
            target = container
        }
    } else if (target instanceof $) {
        target = target[0]
    }
    ReactDOM.render(jsx, target, call)
}
